package com.bjpowernode.javase.collection;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/*
HashMap集合：
    1、HashMap集合底层是哈希表/散列表的数据结构。
    2、哈希表是怎样的一个数据结构呢？
        哈希表是一个数组和单向链表的结合体。
        数组：在查询方面效率很高，随机增删方面效率很低。
        单向链表：在随机增删方面效率较高，在查询方面效率较低。
        哈希表将以上的两种数据结构融合在一起，充分发挥各自的优点。
     3、HashMap集合底层的源代码：
     public class HashMap{

        //HashMao底层实际上就是一个数组，一维数组，一维数组里面存储的是Node。
        Node<K,V>[] table;

        static class Node<K,V> implements Map.Entry<K,V>{

        final int hash;//Hash值（Hash值是key的HashCode()方法的执行结果，Hash值通过哈希函数/算法，可以转换成数组的下标）
        final K key;//存储到Map集合中的key
        V value;//存储到Map集合中的value
        Node<K,V> next;//下一个节点的内存地址
        }
     }
     哈希表/散列表：一维数组，这个数组中每一个元素是一个单向链表，是数组和单向链表的结合体。
     4、最主要掌握的是：
        map.put(K,V)
        v = map.get(K)

     5、HashMap集合的key部分的特点：
        无序，不可重复。
        为什么无序？ 因为不一定挂到那个单向链表上。
        为什么不可重复？因为equals方法保证map集合的key不可重复。如果key重复了value会覆盖

        放在hashMap集合key部分中的元素其实就是放到HashSet集合中了
        因为HashSet集合也需要重写HashCode()和equals()方法。
     6、哈希表Hashmap使用不当时无法发挥性能！

        假设所有的HashCode()方法返回值一样，那么将导致哈希表变成了纯单向链表。
        这种情况称为散列分部不均匀。

        假设所有的HashCode()方法返回值都不一样，那么将导致哈希表变成了纯一维数组。
        也是散列分部不均匀。

        散列分部均匀需要HashCode方法重写时有一定的技巧。

     7、HashMap集合数组的初始容量是16，扩容之后是原容量的二倍，默认加载因子是0.75.
        默认加载因子是当HashMap集合底层数组的容量达到75%的时候，数组开始扩容。
        重点：HashMap集合初始化容量必须是二的倍数，这是官方推荐的。
        这是因为达到散列均匀，为了提高HashMap集合的存取效率所必须的。



    */
public class HashMapTest01 {
    public static void main(String[] args) {

        //测试hashMap集合key部分元素的特点
        //Integer的HashCode和equals都重写了
        Map<Integer,String> map = new HashMap<>();
        map.put(111,"zhangsan");
        map.put(666,"lisi");
        map.put(777,"wangwu");
        map.put(222,"zhaoliu");
        map.put(222,"king");//key重复的时候value会自动覆盖

        System.out.println(map.size());

        //遍历map集合
        Set<Map.Entry<Integer,String>> set = map.entrySet();
        for(Map.Entry<Integer,String> entry : set){
            //验证结果：hashMap集合可以部分无序不可重复。
            System.out.println(entry.getKey() + "=" + entry.getValue());
        }

        map.forEach((key,value)-> System.out.println(key+" "+value));
    }
}
